const request = require('./request')
const promisify = require('./promisify')

/**
 * 支付工具类
 */
class PaymentService {
  constructor() {
    // 是否使用模拟支付
    this.useMock = true
    
    // 支付方式
    this.paymentMethods = {
      WECHAT_PAY: '微信支付',
      ALIPAY: '支付宝',
      CASH: '货到付款'
    }

    // 微信支付
    this.wxPayPromisify = promisify(wx.requestPayment)
  }

  /**
   * 发起订单支付
   * @param {number} orderId 订单ID
   * @param {number} amount 支付金额
   * @param {string} method 支付方式
   */
  async payOrder(orderId, amount, method = 'WECHAT_PAY') {
    console.log(`发起支付：订单ID=${orderId}, 金额=${amount}, 方式=${method}`)
    
    // 判断支付方式
    if (method === 'CASH') {
      // 货到付款无需在线支付
      return this.confirmPayment(orderId, method, 'CASH_' + Date.now())
    }
    
    try {
      // 模拟支付或真实支付
      if (this.useMock) {
        return await this.mockPay(orderId, amount, method)
      } else {
        if (method === 'WECHAT_PAY') {
          return await this.wxPay(orderId, amount)
        } else if (method === 'ALIPAY') {
          return await this.aliPay(orderId, amount)
        } else {
          throw new Error('不支持的支付方式: ' + method)
        }
      }
    } catch (error) {
      console.error('支付失败:', error)
      return {
        success: false,
        message: error.message || '支付失败'
      }
    }
  }

  /**
   * 模拟支付过程
   */
  async mockPay(orderId, amount, method) {
    return new Promise((resolve) => {
      wx.showLoading({ title: '支付处理中...' })
      
      // 展示支付信息
      console.log(`[模拟支付] 订单ID: ${orderId}, 金额: ${amount}, 方式: ${method}`)
      
      // 模拟支付成功
      setTimeout(async () => {
        wx.hideLoading()
        
        // 弹出支付确认
        wx.showModal({
          title: '模拟支付',
          content: `是否确认支付${amount}元？`,
          success: async (res) => {
            if (res.confirm) {
              // 用户确认支付
              try {
                // 生成交易号
                const transactionId = method + '_' + Date.now() + '_' + Math.floor(Math.random() * 1000)
                
                // 确认支付
                const result = await this.confirmPayment(orderId, method, transactionId)
                resolve(result)
              } catch (error) {
                resolve({
                  success: false,
                  message: error.message || '支付确认失败'
                })
              }
            } else {
              // 用户取消支付
              resolve({
                success: false,
                message: '用户取消支付'
              })
            }
          }
        })
      }, 1000)
    })
  }

  /**
   * 微信支付
   */
  async wxPay(orderId, amount) {
    try {
      // 1. 获取支付参数
      const paymentParams = await this.getPaymentParams(orderId, 'WECHAT_PAY')
      
      // 2. 调用微信支付
      return new Promise((resolve, reject) => {
        this.wxPayPromisify({
          timeStamp: paymentParams.timeStamp,
          nonceStr: paymentParams.nonceStr,
          package: paymentParams.package,
          signType: paymentParams.signType,
          paySign: paymentParams.paySign
        })
        .then(() => {
          // 3. 支付成功，查询订单状态
          return this.queryPaymentResult(orderId)
        })
        .then(result => {
          resolve({
            success: true,
            orderInfo: result
          })
        })
        .catch(err => {
          // 判断是否是用户取消
          if (err.errMsg && err.errMsg.indexOf('requestPayment:fail cancel') >= 0) {
            resolve({
              success: false,
              cancelled: true,
              message: '用户取消支付'
            })
          } else {
            console.error('微信支付失败:', err)
            reject(err)
          }
        })
      })
    } catch (error) {
      console.error('发起微信支付失败:', error)
      throw error
    }
  }

  /**
   * 支付宝支付
   */
  async aliPay(orderId, amount) {
    // 当前小程序环境不支持支付宝支付
    // 这里返回错误或引导用户使用其他支付方式
    throw new Error('当前环境不支持支付宝支付，请选择微信支付')
  }

  /**
   * 获取支付参数
   */
  async getPaymentParams(orderId, method) {
    try {
      // 请求后端获取支付参数
      const res = await request.post('/payments/prepare', {
        orderId,
        method
      }, {
        mock: {
          timeStamp: '' + Math.floor(Date.now() / 1000),
          nonceStr: 'mock_nonce_' + Math.random().toString(36).substr(2, 15),
          package: 'prepay_id=wx' + Date.now(),
          signType: 'MD5',
          paySign: 'mock_sign_' + Math.random().toString(36).substr(2, 32)
        }
      })
      
      if (res.code === 200 && res.data) {
        return res.data
      } else {
        throw new Error(res.message || '获取支付参数失败')
      }
    } catch (error) {
      console.error('获取支付参数失败:', error)
      throw error
    }
  }

  /**
   * 确认支付
   */
  async confirmPayment(orderId, method, transactionId) {
    try {
      // 请求后端确认支付
      const res = await request.post(`/orders/${orderId}/payment`, {
        paymentMethod: method,
        transactionId
      }, {
        mock: { success: true, message: '支付确认成功' }
      })
      
      if (res.code === 200) {
        return {
          success: true,
          message: '支付成功',
          data: res.data
        }
      } else {
        throw new Error(res.message || '支付确认失败')
      }
    } catch (error) {
      console.error('确认支付失败:', error)
      throw error
    }
  }

  /**
   * 查询支付状态
   */
  async queryPaymentStatus(orderId) {
    try {
      const res = await request.get(`/orders/${orderId}`, {}, {
        mock: {
          id: orderId,
          status: 'PAID',
          paymentMethod: 'WECHAT_PAY',
          paymentTransactionId: 'wx_' + Date.now(),
          paidAt: new Date().toISOString()
        }
      })
      
      if (res.code === 200 && res.data) {
        return {
          success: true,
          data: res.data
        }
      } else {
        throw new Error(res.message || '查询支付状态失败')
      }
    } catch (error) {
      console.error('查询支付状态失败:', error)
      throw error
    }
  }
  
  /**
   * 设置是否使用模拟支付
   */
  setUseMock(useMock) {
    this.useMock = useMock
    console.log(`[Payment] ${useMock ? '启用' : '禁用'}模拟支付`)
  }

  /**
   * 查询支付结果
   */
  async queryPaymentResult(orderId) {
    return new Promise((resolve, reject) => {
      // 最多轮询5次，每次间隔1秒
      let count = 0
      const maxCount = 5
      
      function query() {
        count++
        
        request.get(`/payments/status/${orderId}`, {}, {
          // 模拟支付结果
          mock: {
            orderId: orderId,
            paid: true,
            status: 'PAID',
            paymentMethod: 'WECHAT_PAY',
            paymentTime: new Date().toISOString()
          }
        })
        .then(res => {
          if (res.code === 200 && res.data) {
            if (res.data.paid) {
              // 支付成功
              resolve(res.data)
            } else {
              // 未支付，但仍在处理中
              if (count < maxCount) {
                setTimeout(query, 1000)
              } else {
                // 超过最大轮询次数，视为支付失败
                reject(new Error('支付结果查询超时'))
              }
            }
          } else {
            reject(new Error(res.message || '查询支付结果失败'))
          }
        })
        .catch(err => {
          reject(err)
        })
      }
      
      // 立即开始第一次查询
      query()
    })
  }
}

// 创建单例
const payment = new PaymentService()

module.exports = payment 